using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;

public class PersonaModel : MonoBehaviour
{
	private class ModelParts
	{
		public List<GameObject> models = new List<GameObject>();

		public CustomisationConfig.LookSetType partType;
	}

	private List<Transform> partsToUpdateForTransparentShader = new List<Transform>();

	private List<Transform> partsToUpdateForAmbientShader = new List<Transform>();

	private List<ModelParts> _parts;

	private List<ModelParts> parts
	{
		get
		{
			if (_parts == null)
			{
				_parts = new List<ModelParts>();
				foreach (CustomisationConfig.BodyPartModelDefinition modelDefinition in CustomisationConfig.instance.modelDefinitions)
				{
					ModelParts modelParts = new ModelParts();
					modelParts.partType = modelDefinition.type;
					AddChildrenPartsRecursive(modelParts, base.transform);
					_parts.Add(modelParts);
				}
			}
			return _parts;
		}
	}

	private void AddChildrenPartsRecursive(ModelParts myParts, Transform myStart)
	{
		List<string> nameForType = CustomisationConfig.instance.GetNameForType(myParts.partType);
		if (nameForType == null)
		{
			return;
		}
		for (int i = 0; i < myStart.childCount; i++)
		{
			Transform child = myStart.GetChild(i);
			foreach (string item in nameForType)
			{
				string pattern = item + "[0-9]*";
				Regex regex = new Regex(pattern);
				if (regex.IsMatch(child.name))
				{
					myParts.models.Add(child.gameObject);
				}
			}
			AddChildrenPartsRecursive(myParts, child);
		}
	}

	public void ClearPartsForType(CustomisationConfig.LookSetType partType)
	{
		ModelParts partsForType = GetPartsForType(partType);
		if (partsForType == null)
		{
			return;
		}
		foreach (GameObject model in partsForType.models)
		{
			partsToUpdateForTransparentShader.Remove(model.transform);
			partsToUpdateForAmbientShader.Remove(model.transform);
			model.SetActive(false);
		}
	}

	private ModelParts GetPartsForType(CustomisationConfig.LookSetType partType)
	{
		foreach (ModelParts part in parts)
		{
			if (part.partType == partType)
			{
				return part;
			}
		}
		return null;
	}

	public void ApplyModelLook(CustomisationConfig.LookSetType partType, CustomisationConfig.LookProperty property, CustomisationConfig.ShaderConfig shaderConfig)
	{
		ModelParts partsForType = GetPartsForType(partType);
		if (partsForType == null)
		{
			return;
		}
		foreach (GameObject model in partsForType.models)
		{
			if (model.name.ToLower() == property.modelName.ToString().ToLower())
			{
				ApplyLookToModel(model, property, shaderConfig);
				if (shaderConfig.ShouldUpdateWithBallPos())
				{
					partsToUpdateForTransparentShader.Add(model.transform);
				}
				if (shaderConfig.shouldUpdateWithAmbient)
				{
					partsToUpdateForAmbientShader.Add(model.transform);
				}
			}
		}
	}

	private void ApplyLookToModel(GameObject model, CustomisationConfig.LookProperty property, CustomisationConfig.ShaderConfig shaderConfig)
	{
		model.SetActive(true);
		Texture texture = GetTexture(property.mainTexture);
		Renderer component = model.GetComponent<Renderer>();
		component.material.shader = shaderConfig.shaderName;
		shaderConfig.ApplyOn(component.material);
		shaderConfig.InitMaterial(component.material);
		component.material.SetTexture(shaderConfig.mainTexturePropName, texture);
		Texture texture2 = GetTexture(property.colourTexture);
		component.material.SetTexture(shaderConfig.secondTexturePropName, texture2);
		Texture texture3 = GetTexture(property.normalTexture);
		component.material.SetTexture(shaderConfig.normalTexturePropName, texture3);
		component.material.SetColor(shaderConfig.colourRedPropName, property.colourRed);
		component.material.SetColor(shaderConfig.colourGreenPropName, property.colourGreen);
		component.material.SetColor(shaderConfig.colourBluePropName, property.colourBlue);
		component.material.SetFloat(shaderConfig.highlightPowerPropName, property.highlightPower);
		component.material.SetFloat(shaderConfig.highlightPowerRedPropName, property.highlightPowerRed);
		component.material.SetFloat(shaderConfig.highlightPowerGreenPropName, property.highlightPowerGreen);
		component.material.SetFloat(shaderConfig.highlightPowerBluePropName, property.highlightPowerBlue);
		component.material.SetFloat(shaderConfig.specularFocusPropName, property.specularFocus);
		component.material.SetFloat(shaderConfig.specularStrengthPropName, property.specularStrength);
		component.material.SetFloat(shaderConfig.rimFocusPropName, property.rimFocus);
		component.material.SetFloat(shaderConfig.rimStrengthPropName, property.rimStrength);
	}

	private Texture GetTexture(string textureName)
	{
		if (!string.IsNullOrEmpty(textureName))
		{
			string text = "CharacterTextures/";
			return Resources.Load<Texture>(text + textureName);
		}
		return null;
	}

	public List<Transform> GetPartsToUpdateForTransparency()
	{
		return partsToUpdateForTransparentShader;
	}

	public List<Transform> GetPartsToUpdateForAmbient()
	{
		return partsToUpdateForAmbientShader;
	}
}
